from django.contrib.contenttypes.models import ContentType
from django.core.mail import EmailMultiAlternatives
from django.core.urlresolvers import reverse
from django.db import models
from django.template.loader import render_to_string
from paypal.standard.ipn.models import PayPalIPN
from paypal.standard.ipn.signals import payment_was_successful, payment_was_flagged
from studenthoods.apps.world.models import Testimonial
import settings

ORDER_STATUS = (
        (settings.ORDER_WAITING, settings.ORDER_WAITING),
        (settings.ORDER_CANCELLED, settings.ORDER_CANCELLED),
        (settings.ORDER_FLAGGED, settings.ORDER_FLAGGED),
        (settings.ORDER_COMPLETE, settings.ORDER_COMPLETE),
    )

class Shop(models.Model):
    name = models.CharField(max_length=60)
    slug = models.SlugField(db_index=True, unique=True, max_length=60)
    slug_hash = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    opening_date = models.DateField()
    closing_date = models.DateField()
    order_target = models.IntegerField()
    price = models.DecimalField(max_digits=16, decimal_places=2)
    address_required = models.BooleanField()
    default_hoodie_image = models.FileField(upload_to='img/hoodie-colour/', null=True, blank=True)

    def colours(self):
        try:
            return HoodieColour.objects.all().filter(shop__id=self.id)
        except:
            pass
        
    @property
    def available_colours(self):
        list = '';
        colours = self.colours()
        i = 0
        
        for colour in colours:
            list += colour.colour
            if i != (len(colours)-1):
                 list+= ', '
            i+=1
        return list

    @models.permalink
    def get_absolute_url(self):
        return ('shop', (), {'slug_shop': self.slug})

    def __unicode__(self):
        return str(self.slug)

class HoodieColour(models.Model):
    colour = models.CharField(max_length=15)
    slug = models.SlugField(max_length=15)
    rgb = models.CharField(max_length=6)
    shop = models.ForeignKey(Shop,related_name='hoodie_colour_colour')
    image = models.FileField(upload_to='img/hoodie-colour/', null=True, blank=True)
    
    def sizes(self):
        try:
            return HoodieSize.objects.all().filter(colour=self)
        except:
            return []
    
    @property
    def available_sizes(self):
        list = '';
        sizes = self.sizes()
        i = 0
        
        print len(sizes)
        for size in sizes:
            list += size.size
            if i != (len(sizes)-1):
                 list+= ', '
            i+=1
        return list
    
    def __unicode__(self):
        return str(self.colour)
    
    def get_sizes_url(self):
        return str(reverse('shop_sizes', kwargs={'slug_shop':self.shop.slug, 'slug_colour':self.slug}))

class HoodieSize(models.Model):
    SIZES = (
        (u'XXS', u'XXS'),
        (u'XS', u'XS'),
        (u'S', u'S'),
        (u'M', u'M'),
        (u'L', u'L'),
        (u'XL', u'XL'),
        (u'XXL', u'XXL'),
    )
    size = models.CharField(max_length=5, choices=SIZES)
    colour = models.ForeignKey(HoodieColour,related_name='hoodie_size_colour')

    def __unicode__(self):
        return str(self.size)

class Order(models.Model):
    first_name = models.CharField(max_length = 15)
    surname = models.CharField(max_length = 15)
    email = models.EmailField(max_length = 40)
    phone_number = models.CharField(max_length = 15)
    shop = models.ForeignKey(Shop)
    size = models.CharField(max_length = 5)
    colour = models.CharField(max_length = 15)
    hash = models.CharField(max_length = 200)
    created_at = models.DateTimeField(auto_now=True)
    address_line_1 = models.CharField(max_length = 25, null = True, blank= True)
    address_line_2 = models.CharField(max_length = 25, null = True, blank= True)
    city = models.CharField(max_length = 25, null=True, blank=True)
    postcode = models.CharField(max_length = 10, null=True, blank= True)
    status = models.CharField(max_length = 15, choices = ORDER_STATUS, default=settings.ORDER_WAITING, null = True, blank = True)
    email_new_order_sent = models.BooleanField(default = False)
    ipn = models.ForeignKey(PayPalIPN, null = True, blank= True)
    
    @property
    def name(self):
        return self.first_name + ' ' +self.surname
    
    @property
    def address(self):
        if self.address_line_1:
            return self.address_line_1 + ', ' + self.address_line_2 + ', ' + self.city + ', ' + self.postcode
        else:
            return 'no address required'
    
    @property
    def order_details(self):
        return self.shop.name + ' ' + self.colour + ' ' + self.size
    
    @property
    def hoodie(self):
        return HoodieColour.objects.get(shop__id = self.shop.id, colour = self.colour)
    
    @property
    def url_cancel_return(self):
        from studenthoods.apps.shop.utils import get_site_url
        return get_site_url(reverse('shop_paypal_cancel_return', kwargs={'hash':self.hash}))
    
    @property
    def url_notify(self):
        from studenthoods.apps.shop.utils import get_site_url
        return get_site_url(reverse('paypal-ipn'))
    
    @property
    def url_return(self):
        from studenthoods.apps.shop.utils import get_site_url
        return get_site_url(reverse('shop_paypal_return', kwargs={'hash':self.hash}))
    
    @property
    def get_admin_url(self):
        from studenthoods.apps.shop.utils import get_site_url
        content_type = ContentType.objects.get_for_model(self.__class__)
        return get_site_url(reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)))
    
    def email_new_order(self):
        context = {'order' : self}
        text = render_to_string('email_new_order.txt', context)
        html = render_to_string('email_new_order.html', context)
                
        msg = EmailMultiAlternatives('StudentHoods: New Order - ' + str(self.id), text, settings.DEFAULT_FROM_EMAIL, [settings.EMAIL_CONTACT_RECEIVER])
        msg.attach_alternative(html, 'text/html')
        msg.send()
        
    def email_new_order_flagged(self):
        context = {'order' : self}
        text = render_to_string('email_new_order_flagged.txt', context)
        html = render_to_string('email_new_order_flagged.html', context)
                
        msg = EmailMultiAlternatives('StudentHoods: New Order - ' + str(self.id), text, settings.DEFAULT_FROM_EMAIL, [settings.EMAIL_CONTACT_RECEIVER])
        msg.attach_alternative(html, 'text/html')
        msg.send()
    
    def payment_successful(sender, **kwargs):
        ipn_obj = sender
        
        if ipn_obj:
            ipn_obj.save()
            
            try:
                order = Order.objects.get(hash = ipn_obj.custom)
                order.status = settings.ORDER_COMPLETE
                order.ipn = ipn_obj
                order.save()

                if not order.email_new_order_sent:
                    order.email_new_order()
                    order.email_new_order_sent = True;
                    order.save()
            except Order.DoesNotExist:
                pass
    payment_was_successful.connect(payment_successful)
    
    def payment_flagged(sender, **kwargs):
        ipn_obj = sender
        
        if ipn_obj:
            ipn_obj.save()
            
            try:
                order = Order.objects.get(hash = ipn_obj.custom)
                order.status = settings.ORDER_FLAGGED
                order.ipn = ipn_obj
                order.save()
    
                if not order.email_new_order_sent:
                    order.email_new_order_flagged()
                    order.email_new_order_sent = True;
                    order.save()
            except Order.DoesNotExist:
                pass
    payment_was_flagged.connect(payment_flagged)

    def __unicode__(self):
        return str(self.id)